<script setup lang="ts">
import { CreateOrUpdateTaskData } from "@/api/task/types/static-task"
import { ElMessage, FormInstance, FormRules } from "element-plus"
import { cloneDeep } from "lodash-es"
import { onMounted, ref } from "vue"
import { FormTypeEnum, TabTypeEnum, taskModeOptions } from "@/constants/other-keys"
import { closeRoute } from "@/hooks/useCloseRouteListener"
import { getSceneListApi } from "@/api/resources/scene"
import { SceneTableData } from "@/api/resources/scene/types/scene"
import { createTaskDataApi, getTaskInfoApi, updateTaskDataApi } from "@/api/task"
import { useRoute } from "vue-router"
import { getSourceOptionsApi } from "@/api/resources/source"
import { SourceViewInfo } from "@/api/resources/source/types/source"

defineOptions({
  // 命名当前组件
  name: "TaskEdit"
})

interface Props {
  formType: FormTypeEnum
}
const props = defineProps<Props>()
const DEFAULT_FORM_DATA: CreateOrUpdateTaskData = {
  task_id: undefined,
  /** 任务名称 */
  task_name: "",
  /** 任务描述 */
  task_describe: "",
  /** 场景id */
  game_id: "",
  /** 任务类型 */
  task_type: TabTypeEnum.STATIC,
  /** 源数据资源 */
  associate_id: undefined,
  /** 任务算法标签 */
  task_tag: "",
  /** 任务状态 */
  task_status: 0,
  /** task_param */
  task_param: {
    task_config: {
      mode: "Train",
      resources: {
        distributed_enable: false,
        gpu_num: 1
      }
    },
    episode_config: {
      max_episode: 1,
      batch_num: 64
    },
    test_config: {
      test_enable: true
    },
    save_config: {
      algorithm_model: {
        save_enable: true
      }
    }
  }
}
const loading = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<CreateOrUpdateTaskData>(cloneDeep(DEFAULT_FORM_DATA))
const formRules: FormRules<CreateOrUpdateTaskData> = {
  task_name: [{ required: true, trigger: "blur", message: "请输入任务名称" }],
  game_id: [{ required: true, trigger: "change", message: "请选择任务场景" }],
  "task_param.task_config.mode": [{ required: true, trigger: "change", message: "请选择任务模式" }]
}
const taskSceneOptions = ref<SceneTableData[]>([])
const sourceOptions = ref<SourceViewInfo[]>([])
const route = useRoute()

const handleCreateOrUpdate = () => {
  formRef.value?.validate((valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)
    loading.value = true
    const api = props.formType == FormTypeEnum.CREATE ? createTaskDataApi : updateTaskDataApi
    api({
      task_id: formData.value.task_id,
      task_name: formData.value.task_name,
      task_describe: formData.value.task_describe,
      game_id: formData.value.game_id,
      task_type: TabTypeEnum.STATIC,
      task_status: formData.value.task_status,
      associate_id: formData.value.associate_id,
      task_tag: formData.value.task_tag,
      task_param: formData.value.task_param
    })
      .then(() => {
        ElMessage.success("操作成功")
        loading.value = false
        handleCancel()
      })
      .finally(() => {
        loading.value = false
      })
  })
}
const resetForm = () => {
  formRef.value?.clearValidate()
  formData.value = cloneDeep(DEFAULT_FORM_DATA)
}
const handleCancel = () => {
  resetForm()
  closeRoute()
}
const getSceneOptions = () => {
  getSceneListApi(TabTypeEnum.STATIC)
    .then(({ data }) => {
      taskSceneOptions.value = data
    })
    .catch(() => {
      taskSceneOptions.value = []
    })
}
const getSourceOptions = () => {
  getSourceOptionsApi()
    .then(({ data }) => {
      sourceOptions.value = data
    })
    .catch(() => {
      sourceOptions.value = []
    })
}
const getTaskInfo = (id: string) => {
  getTaskInfoApi(id).then(({ data }) => {
    formData.value = {
      task_id: data.task_id,
      task_name: data.task_name,
      task_describe: data.task_describe,
      game_id: data.game_id,
      task_type: TabTypeEnum.STATIC,
      task_status: data.task_status,
      task_tag: data.task_tag,
      associate_id: data.associate_id,
      task_param: JSON.parse(data.task_param)
    }
  })
}

onMounted(() => {
  if (route.query.id != null) {
    getTaskInfo(route.query.id as string)
  }
  getSourceOptions()
  getSceneOptions()
})
</script>

<template>
  <el-form
    ref="formRef"
    class="taskedit-form"
    :model="formData"
    :disabled="props.formType == FormTypeEnum.VIEW"
    :rules="props.formType == FormTypeEnum.VIEW ? {} : formRules"
    label-width="auto"
    size="large"
  >
    <div class="title">
      <svg-icon name="icon-task" />
      <h3>任务信息</h3>
    </div>
    <el-row>
      <el-form-item label="任务名称" prop="task_name">
        <el-input v-model="formData.task_name" :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请输入'" />
      </el-form-item>
      <el-form-item label="任务场景" prop="game_id">
        <el-select
          v-model="formData.game_id"
          clearable
          :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请选择'"
          style="width: 240px"
        >
          <el-option
            v-for="item in taskSceneOptions"
            :key="item.game_id"
            :label="item.game_name"
            :value="item.game_id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="任务模式" prop="task_param.task_config.mode">
        <el-select
          v-model="formData.task_param.task_config.mode"
          clearable
          :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请选择'"
          style="width: 240px"
        >
          <el-option v-for="item in taskModeOptions" :key="item.value" :label="item.name" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="源数据资源" prop="associate_id">
        <el-select
          v-model="formData.associate_id"
          clearable
          :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请选择'"
          style="width: 240px"
        >
          <el-option
            v-for="item in sourceOptions"
            :key="item.raw_data_id"
            :label="item.raw_data_name"
            :value="item.raw_data_id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="算法标签" prop="task_tag">
        <el-input v-model="formData.task_tag" :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请输入'" />
      </el-form-item>
    </el-row>
    <el-form-item label="任务描述" prop="task_describe">
      <el-input
        v-model="formData.task_describe"
        :rows="3"
        type="textarea"
        :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请输入'"
      />
    </el-form-item>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-resource" />
      <h3>资源配置</h3>
    </div>
    <el-form-item label="算法分布能力" prop="task_param.task_config.resources.distributed_enable">
      <el-switch v-model="formData.task_param.task_config.resources.distributed_enable" />
    </el-form-item>
    <el-row>
      <el-form-item label="GPU数量" prop="task_param.task_config.resources.gpu_num">
        <el-input
          :disabled="!formData.task_param.task_config.resources.distributed_enable"
          v-model="formData.task_param.task_config.resources.gpu_num"
          :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请输入'"
        />
      </el-form-item>
    </el-row>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-train" />
      <h3>训练配置</h3>
    </div>
    <el-form-item label="最大轮数" prop="task_param.episode_config.max_episode">
      <el-input
        v-model="formData.task_param.episode_config.max_episode"
        :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请输入'"
        style="width: 200px"
        :controls="false"
      />
    </el-form-item>
    <el-form-item label="批次量" prop="task_param.episode_config.batch_num">
      <el-input
        v-model="formData.task_param.episode_config.batch_num"
        :placeholder="props.formType == FormTypeEnum.VIEW ? '' : '请输入'"
        style="width: 200px"
        :controls="false"
      />
    </el-form-item>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-test" />
      <h3>测试配置</h3>
    </div>
    <el-row>
      <el-form-item label="是否测试" prop="task_param.test_config.test_enable">
        <el-switch v-model="formData.task_param.test_config.test_enable" />
      </el-form-item>
    </el-row>
    <el-divider />
    <div class="title">
      <svg-icon name="icon-save" />
      <h3>保存配置</h3>
    </div>
    <el-form-item label="算法模型" prop="task_param.save_config.training_sample_data.save_enable">
      <el-space>
        开启存储
        <el-switch
          :disabled="formData.task_param.task_config.mode == 'Inference'"
          v-model="formData.task_param.save_config.algorithm_model.save_enable"
        />
      </el-space>
    </el-form-item>
    <div class="form-footer" v-if="props.formType != FormTypeEnum.VIEW">
      <el-button type="primary" @click="handleCreateOrUpdate" :loading="loading">保 存</el-button>
      <el-button @click="handleCancel">取 消</el-button>
    </div>
  </el-form>
  <div class="form-footer" v-if="props.formType == FormTypeEnum.VIEW">
    <el-button @click="handleCancel">关 闭</el-button>
  </div>
</template>
<style lang="scss" scoped>
.form-footer {
  display: flex;
  justify-content: center;
  padding-bottom: 20px;
}
.taskedit-form {
  margin: 0 auto;
  margin-top: 0;
  .title {
    display: flex;
    flex-direction: row;
    align-items: center;
    line-height: 42px;
    .svg-icon {
      width: 2em;
      height: 2em;
    }
    h3 {
      margin-left: 10px;
    }
  }
}

@media screen and (max-width: 640px) {
  .taskedit-form {
    width: 100%;
  }
}
@media screen and (min-width: 660px) {
  .taskedit-form {
    width: 80%;
  }
}
@media screen and (min-width: 1200px) {
  .taskedit-form {
    width: 60%;
  }
}
</style>
